package com.crm.system.service.impl.orderManager;

import com.alibaba.fastjson.JSONObject;
import com.crm.common.model.DhPageInfo;
import com.crm.common.util.CommonUtils;
import com.crm.model.entity.orderManager.CustomerOrderInvoice;
import com.crm.model.entity.orderManager.CustomerOrderInvoiceLog;
import com.crm.model.entity.returnMoney.ReturnMoney;
import com.crm.model.entity.sys.UserAccount;
import com.crm.model.entity.sys.permissionManagement.SysRequestPtInvoiceLog;
import com.crm.model.qo.orderManager.OrderInvoiceQO;
import com.crm.model.vo.orderManager.ApplyInvoiceOrderInfoVO;
import com.crm.model.vo.orderManager.ApplyOrderInvoiceInfoVO;
import com.crm.model.vo.orderManager.OrderInvoiceVO;
import com.crm.model.vo.orderManager.PtInvoiceBlueResultVO;
import com.crm.model.vo.sys.CompanyProjectVO;
import com.crm.model.vo.sys.InvoiceCompanyVO;
import com.crm.service.orderManager.CustomerOrderInvoiceDbService;
import com.crm.service.orderManager.CustomerOrderInvoiceLogDbService;
import com.crm.service.orderManager.CustomerProductOrderDbService;
import com.crm.service.returnMoney.ReturnMoneyDbservice;
import com.crm.service.sys.permissionManagement.CompanyProjectDbService;
import com.crm.service.sys.permissionManagement.InvoiceCompanyDbService;
import com.crm.service.sys.permissionManagement.RequestPtInvoiceLogDbService;
import com.crm.system.service.orderManager.CustomerOrderInvoiceService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.vpiaotong.openapi.OpenApi;
import com.vpiaotong.openapi.util.Base64Util;
import com.vpiaotong.openapi.util.HttpUtils;
import com.vpiaotong.openapi.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author:chaifuyou
 * @Date: 2021/4/26 11:41
 */
@Service
@Slf4j
public class CustomerOrderInvoiceServiceImpl implements CustomerOrderInvoiceService {

    @Autowired
    private CustomerOrderInvoiceDbService customerOrderInvoiceDbService;

    @Autowired
    private ReturnMoneyDbservice returnMoneyDbservice;

    @Autowired
    CustomerProductOrderDbService customerProductOrderDbService;

    @Autowired
    CustomerOrderInvoiceLogDbService customerOrderInvoiceLogDbService;

    @Autowired
    CompanyProjectDbService companyProjectDbService;

    @Autowired
    InvoiceCompanyDbService invoiceCompanyDbService;

    @Autowired
    RequestPtInvoiceLogDbService requestPtInvoiceLogDbService;

    @Value("${platform_alias}")
    private String platform_alias;

    @Value("${invoice_url}")
    private String invoice_url;

    @Value("${pt_private_key}")
    private String privateKey;

    @Value("${pt_public_key}")
    private String ptPublicKey;

    @Value("${password}")
    private String password;

    @Value("${platform_code}")
    private String platform_code;

    /**
     * 财务-新增开票信息记录
     * @param customerOrderInvoiceLog
     */
    @Override
    public PtInvoiceBlueResultVO addOrderInvoiceLog(List<CustomerOrderInvoiceLog> customerOrderInvoiceLog) {
        UserAccount userAccount = (UserAccount) SecurityUtils.getSubject().getPrincipal();//当前登录人信息
        PtInvoiceBlueResultVO resultVO = new PtInvoiceBlueResultVO();
        if (customerOrderInvoiceLog.size() < 1){
            resultVO.setCode("0001");
            resultVO.setMsg("没有选择产品信息");
            return resultVO;
        }
        CustomerOrderInvoice customerOrderInvoice = customerOrderInvoiceDbService.selectByPrimaryKey(customerOrderInvoiceLog.get(0).getChsCustomerOrderInvoiceId());
        BigDecimal invoiceMoneyCount = new BigDecimal("0");
        for (int i =0;i<customerOrderInvoiceLog.size();i++){
            invoiceMoneyCount = invoiceMoneyCount.add(customerOrderInvoiceLog.get(i).getInvoiceMoney());
        }
        BigDecimal big = customerOrderInvoiceLogDbService.getSumApplyInvoiceMoney(customerOrderInvoiceLog.get(0).getChsCustomerOrderInvoiceId());
        invoiceMoneyCount = invoiceMoneyCount.add(big);
        if (invoiceMoneyCount.compareTo(customerOrderInvoice.getInvoiceMoney()) == 1){
            resultVO.setCode("0002");
            resultVO.setMsg("累计开票金额大于申请开票金额");
            return resultVO;
        }
        InvoiceCompanyVO invoiceCompanyVO = invoiceCompanyDbService.selectInvoiceCompanyByInvoiceId(customerOrderInvoiceLog.get(0).getChsCustomerOrderInvoiceId());
        OrderInvoiceVO orderInvoiceVO = customerOrderInvoiceDbService.selectOrderInvoiceById(customerOrderInvoiceLog.get(0).getChsCustomerOrderInvoiceId());
        CompanyProjectVO projectVO = companyProjectDbService.selectCompanyProjectById(customerOrderInvoiceLog.get(0).getCompanyProjectId());
        if (orderInvoiceVO.getInvoiceType() == 2 && Objects.nonNull(invoiceCompanyVO) && Objects.nonNull(orderInvoiceVO) && Objects.nonNull(projectVO)){
            String url = invoice_url;
            Map<String, Object> map = new HashMap<String, Object>();
            //map.put("taxpayerNum", "110105201606160003");  //销方纳税人识别号
            map.put("taxpayerNum", invoiceCompanyVO.getCompanyNumber());  //销方纳税人识别号
            map.put("invoiceReqSerialNo", date());//发票请求流水号
            map.put("buyerName", orderInvoiceVO.getInvoiceTitle());//发票抬头
            if (!"".equals(orderInvoiceVO.getTaxNumber())){
                map.put("buyerTaxpayerNum", orderInvoiceVO.getTaxNumber());//购买方税号(非必填,个人发票传null)
            }
            if (!"".equals(orderInvoiceVO.getAddress())){
                map.put("buyerAddress", orderInvoiceVO.getAddress());//地址
            }
            if (!"".equals(orderInvoiceVO.getPhone())){
                map.put("buyerTel", orderInvoiceVO.getPhone());//电话
            }
            if (!"".equals(orderInvoiceVO.getBankAddress())){
                map.put("buyerBankName", orderInvoiceVO.getBankAddress());//开户行
            }
            if (!"".equals(orderInvoiceVO.getBankAccount())){
                map.put("buyerBankAccount", orderInvoiceVO.getBankAccount());//银行账号
            }

            //销售方参数
            if (!"".equals(invoiceCompanyVO.getCompanyAddress())){
                map.put("sellerAddress", invoiceCompanyVO.getCompanyAddress());//销货方地址
            }
            if (!"".equals(invoiceCompanyVO.getCompanyPhone())){
                map.put("sellerTel", invoiceCompanyVO.getCompanyPhone());//销货方电话
            }
            if (!"".equals(invoiceCompanyVO.getBankAddress())){
                map.put("sellerBankName", invoiceCompanyVO.getBankAddress());//销货方开户行
            }
            if (!"".equals(invoiceCompanyVO.getBankAccount())){
                map.put("sellerBankAccount", invoiceCompanyVO.getBankAccount());//销货方银行账号
            }


            //收款信息
            map.put("casherName", customerOrderInvoiceLog.get(0).getPayee());//收款人
            map.put("reviewerName", customerOrderInvoiceLog.get(0).getReviewer());//复核人
            map.put("drawerName", customerOrderInvoiceLog.get(0).getMakePerson());//开票人

            map.put("takerEmail", orderInvoiceVO.getSendEmail());//邮箱
            if (Objects.nonNull(invoiceCompanyVO.getTaxNumber()) && !"".equals(invoiceCompanyVO.getTaxNumber())){
                map.put("machineCode", invoiceCompanyVO.getTaxNumber());//税盘号
            }
            List<Map<String, String>> list = new ArrayList<Map<String, String>>();
            for (int i=0;i<customerOrderInvoiceLog.size();i++){
                Map<String, String> listMapOne = new HashMap<String, String>();
                listMapOne.put("taxClassificationCode", projectVO.getTaxClassNumber());//税收分类编码
                if (Objects.nonNull(customerOrderInvoiceLog.get(i).getQuantity())){
                    listMapOne.put("quantity", customerOrderInvoiceLog.get(i).getQuantity().toString());//数量
                }
                listMapOne.put("goodsName", customerOrderInvoiceLog.get(i).getProjectName());//货物名称
                if (Objects.nonNull(customerOrderInvoiceLog.get(i).getUnitPrice())){
                    listMapOne.put("unitPrice", customerOrderInvoiceLog.get(i).getUnitPrice().toString());//单价
                }
                listMapOne.put("invoiceAmount", customerOrderInvoiceLog.get(i).getInvoiceMoney().toString());//金额
                listMapOne.put("taxRateValue", customerOrderInvoiceLog.get(i).getTaxRate().toString());//税率
                if (Objects.nonNull(customerOrderInvoiceLog.get(i).getTaxMoney())){
                    listMapOne.put("taxRateAmount", customerOrderInvoiceLog.get(i).getTaxMoney().toString());//税额
                }
                listMapOne.put("includeTaxFlag", "1");//含税标识
                //以下为零税率开票相关参数
                listMapOne.put("zeroTaxFlag", null);//零税率标识(空:非零税率,0:出口零税率,1:免税,2:不征税,3:普通零税率)
                listMapOne.put("preferentialPolicyFlag", null);//优惠政策标识(空:不使用,1:使用)   注:零税率标识传非空 此字段必须填写为"1"
                listMapOne.put("vatSpecialManage", null);//增值税特殊管理(preferentialPolicyFlag为1 此参数必填)
                list.add(listMapOne);
                map.put("itemList", list);
            }
            String content = JsonUtil.toJson(map);
            System.out.println("开始请求票通-->  "+content);
            //OpenApi参数内容(3des秘钥(票通提供),平台编码(票通提供),平台前缀(票通提供),私钥)
            String buildRequest = new OpenApi(password, platform_code, platform_alias, privateKey).buildRequest(content);
            System.out.println("票通返回-->  "+content);
            String response = HttpUtils.postJson(url, buildRequest);

            //插入记录数据
            SysRequestPtInvoiceLog requestPtInvoiceLog = new SysRequestPtInvoiceLog();
            requestPtInvoiceLog.setRequestptPtInvoiceLogId(CommonUtils.getGUID());
            requestPtInvoiceLog.setInvoiceReqSerialNo(map.get("invoiceReqSerialNo").toString());
            requestPtInvoiceLog.setOrderInvoiceLogId(customerOrderInvoiceLog.get(0).getOrderInvoiceLogId());
            requestPtInvoiceLog.setReqData(content);
            requestPtInvoiceLog.setReturnData(response);
            requestPtInvoiceLog.setCreatePeopleId(userAccount.getAccountId());
            requestPtInvoiceLog.setCreateTm(new Date());
            requestPtInvoiceLogDbService.addRequestPtInvoiceLog(requestPtInvoiceLog);


            String contentStr = new OpenApi(password, platform_code, platform_alias, privateKey).disposeResponse(response, ptPublicKey);
            resultVO = JSONObject.parseObject(contentStr, PtInvoiceBlueResultVO.class);
            if ("0000".equals(resultVO.getCode())){  //成功之后的操作
                customerOrderInvoice.setChsCustomerOrderInvoiceId(customerOrderInvoiceLog.get(0).getChsCustomerOrderInvoiceId());
                customerOrderInvoice.setInvoiceReqSerialNo(map.get("invoiceReqSerialNo").toString());
                customerOrderInvoice.setQrCodePath(Base64Util.decode2String(resultVO.getContent().getQrCodePath()));
                //customerOrderInvoice.setQrCode(Base64Util.decode2String(resultVO.getContent().getQrCode()));
                customerOrderInvoice.setQrCode(resultVO.getContent().getQrCode());
                customerOrderInvoice.setUpdatePeopleId(userAccount.getAccountId());
                customerOrderInvoice.setUpdateTm(new Date());
                if (invoiceMoneyCount.compareTo(customerOrderInvoice.getInvoiceMoney()) == 0){
                    customerOrderInvoice.setInvoiceStatus(1);
                }else if (invoiceMoneyCount.compareTo(customerOrderInvoice.getInvoiceMoney()) == -1){
                    customerOrderInvoice.setInvoiceStatus(2);
                }
                customerOrderInvoiceDbService.updateOrderInvoice(customerOrderInvoice);

                for (int i=0;i<customerOrderInvoiceLog.size();i++){
                    CustomerOrderInvoiceLog log;
                    log = customerOrderInvoiceLog.get(i);
                    log.setOrderInvoiceLogId(CommonUtils.getGUID());
                    log.setCreatePeopleId(userAccount.getAccountId());
                    log.setCreateTm(new Date());
                    log.setPayee(customerOrderInvoiceLog.get(0).getPayee());
                    log.setReviewer(customerOrderInvoiceLog.get(0).getReviewer());
                    log.setMakePerson(customerOrderInvoiceLog.get(0).getMakePerson());
                    log.setQrCodePath(customerOrderInvoice.getQrCodePath());
                    log.setQrCode(customerOrderInvoice.getQrCode());
                    customerOrderInvoiceLogDbService.addOrderInvoiceLog(log);
                }
                customerOrderInvoiceDbService.updateExamineStatus(customerOrderInvoiceLog.get(0).getChsCustomerOrderInvoiceId(),"1");
            }
        }
        return resultVO;
    }

    /**
     * 新增发票申请
     * @param customerOrderInvoice
     */
    @Override
    public void addOrderInvoice(CustomerOrderInvoice customerOrderInvoice) {
        UserAccount userAccount = (UserAccount) SecurityUtils.getSubject().getPrincipal();//当前登录人信息
        customerOrderInvoice.setInvoiceStatus(0);
        customerOrderInvoice.setChsCustomerOrderInvoiceId(CommonUtils.getGUID());
        customerOrderInvoice.setCreatePeopleId(userAccount.getAccountId());
        customerOrderInvoice.setCreateTm(new Date());
        customerOrderInvoiceDbService.addOrderInvoice(customerOrderInvoice);
    }

    /**
     *查询开票记录
     * @param pageIndex
     * @param pageSize
     * @param sortName
     * @param sortOrder
     * @param qo
     * @return
     */
    @Override
    public DhPageInfo<OrderInvoiceVO> selectOrderInvoiceList(Integer pageIndex, Integer pageSize, String sortName, String sortOrder, OrderInvoiceQO qo) {
        UserAccount userAccount = (UserAccount) SecurityUtils.getSubject().getPrincipal();//当前登录人信息
        if (pageIndex != null && pageSize != null) {
            PageHelper.startPage(pageIndex, pageSize);
        }
        //排序
        StringBuilder order = new StringBuilder();
        if(!StringUtils.isBlank(sortName)&&!StringUtils.isBlank(sortOrder)){
            switch(sortName){
                case "invoiceTm":
                {
                    order.append("i.invoice_tm ").append(sortOrder);//创建时间
                }
                break;
                default:
                    break;
            }
        }
        if ("0".equals(qo.getQx())){  //dept 3是总部财务 4是分公司财务
            if (StringUtils.isEmpty(qo.getCompanyId())){
                if(!CommonUtils.isAdmin(userAccount.getUserId()) && !"3".equals(userAccount.getDeptId())){
                    qo.setCompanyId(userAccount.getCompanyId());
                }
            }

        }else {
            qo.setUserId(userAccount.getAccountId());
        }
        Integer dateUnit=getDateUnit(qo.getDateType());
        List<OrderInvoiceVO> retustList=customerOrderInvoiceDbService.selectOrderInvoiceList(qo,order.toString(),dateUnit);
        PageInfo<OrderInvoiceVO> page =new PageInfo(retustList);
        return new DhPageInfo<OrderInvoiceVO>(page, retustList);
    }

    /**
     * 修改开票审批状态
     * @param id
     * @param type
     */
    @Override
    public void updateExamineStatus(String id, String type) {
        customerOrderInvoiceDbService.updateExamineStatus(id,type);
        //维护回款记录表发票状态
        if ("1".equals(type)){
            CustomerOrderInvoice customerOrderInvoice =customerOrderInvoiceDbService.selectByPrimaryKey(id);
            UserAccount userAccount = (UserAccount) SecurityUtils.getSubject().getPrincipal();//当前登录人信息
            ApplyInvoiceOrderInfoVO vo = customerProductOrderDbService.getApplyInvoiceOrderInfo(null,customerOrderInvoice.getProductOrderId());
            if (Objects.nonNull(vo)){
                ReturnMoney returnMoney = new ReturnMoney();
                returnMoney.setOrderId(vo.getOrderId());
                if ("0".equals(vo.getResidueMoney().toString()) || "0.00".equals(vo.getResidueMoney().toString())){
                    returnMoney.setInvoiceStatus(2);
                }else {
                    returnMoney.setInvoiceStatus(1);
                }
                returnMoney.setUpdateBy(userAccount.getAccountId());
                returnMoney.setUpdateTm(new Date());
                returnMoneyDbservice.updateReturnMoneyByOrderId(returnMoney);
            }
        }
    }

    /**
     * 根据id查询发票信息
     * @param id
     * @return
     */
    @Override
    public CustomerOrderInvoice selectByPrimaryKey(String id) {
        return customerOrderInvoiceDbService.selectByPrimaryKey(id);
    }

    /**
     * 删除开票信息
     * @param id
     */
    @Override
    public void delOrderInvoice(String id) {
        customerOrderInvoiceDbService.delOrderInvoice(id);
    }

    /**
     * 查看发票申请详情
     * @param chsCustomerOrderInvoiceId
     * @return
     */
    @Override
    public ApplyOrderInvoiceInfoVO selectApplyOrderInvoiceInfo(String chsCustomerOrderInvoiceId) {
        return customerOrderInvoiceDbService.selectApplyOrderInvoiceInfo(chsCustomerOrderInvoiceId);
    }

    /**
     * 随机发票流水号生成
     */
    public  String date(){
        Date date = new Date();
        SimpleDateFormat sdf =new SimpleDateFormat("YYYYMMddHHmmss");
        String str=platform_alias+sdf.format(date)+(int)(Math.random()*90+10);
        System.out.println(str);
        return str;
    }


    /**
     * 日期类型(全部/本周/本月/本年度)
     * @Author chaifuyou
     * @Date  2021/4/1 16:12
     * @param dateType -(all:全部; thisWeek:本周; thisMonth:本月; thisYear:本年；thisToday:今天)
     * @return {@link {java.lang.Integer}}
     */
    private Integer getDateUnit(String dateType) {
        Integer dateUnit = 0;
        if (!StringUtils.isBlank(dateType)) {
            if ("thisWeek".equals(dateType)) {
                //本周
                dateUnit = 1;
            }
            if ("thisMonth".equals(dateType)) {
                //本月
                dateUnit = 2;
            }
            if ("thisYear".equals(dateType)) {
                //本年
                dateUnit = 3;
            }
            if ("thisToday".equals(dateType)) {
                //今天
                dateUnit = 4;
            }
        }
        return dateUnit;
    }
}
